1、how to pass data from child to parent

关键词拆解:

  1. Child → Parent

    • 数据流从子组件传到父组件
    • 这是 React 单向数据流(unidirectional data flow) 的逆向传递
  2. Data

    • 可以是事件信息、表单值、状态更新结果等

核心考点:

拆解小问题:

  1. 父组件如何接收数据?

    • 父组件定义一个函数,用来处理子组件传来的数据
  2. 子组件如何传数据?

    • 将父组件的函数通过 props 传给子组件
    • 子组件调用这个函数,把数据作为参数传回父组件

 

In React, the standard way to pass data from a child to a parent is by using callback functions. The parent component defines a function to handle the data, then passes it to the child via props. The child calls this function whenever it wants to send data back. For example:

This pattern, often called lifting state up, keeps React’s unidirectional data flow predictable, while letting children communicate with parents. It’s simple, reusable, and works for most scenarios without adding extra state management libraries.

面试加分点

2、how to render an element outside of component scope/tree?

关键词拆解:

  1. Render outside component tree

    • 意思是把某个 React 元素渲染到 DOM 中不在父组件层次结构的地方
    • 常见场景:模态框(Modal)、工具提示(Tooltip)、Toast 通知等
  2. Component scope/tree

    • 默认情况下,React 元素渲染在其父组件的 DOM 节点内
    • 题目考察你对 React portals 的理解

核心考点:

拆解小问题:

  1. 为什么普通渲染不能满足需求?

    • 父组件可能有 overflow: hidden / relative 等样式限制
    • 模态框可能需要覆盖整个页面
  2. React 提供什么解决方案?

    • ReactDOM.createPortal
    • 可以把子组件渲染到 任意 DOM 节点

In React, when I need to render an element outside the parent component’s DOM hierarchy — for example, a modal, tooltip, or toast — I use React Portals. A portal allows a child component to be rendered into a DOM node that exists outside the parent component’s DOM tree, while still keeping the React tree intact for state and context. For example:

This way, the modal can appear above other components without being constrained by parent styles, but it still behaves like a normal React component in terms of state, props, and context.

面试加分点

3、 how to implement code splitting in your react app and why

关键词拆解:

  1. Code splitting

    • 把应用的 JavaScript 代码分割成多个小的 bundle
    • 用户只加载当前页面需要的代码,而不是整个应用
    • 减少 初次加载时间,提高性能
  2. Implement in React

    • 题目考察你是否熟悉 React 的 动态导入(dynamic import)lazy loading
  3. Why

    • 需要解释为什么这样做:性能优化、用户体验、减少首屏加载

核心考点:

拆解小问题:

  1. 为什么需要 code splitting?

    • 大型应用一次加载所有 JS 会导致首屏渲染慢
    • 用户体验差,尤其在移动端
  2. 如何在 React 中实现?

    • Route-based splitting:按路由加载页面组件
    • Component-based splitting:按组件加载部分功能
    • React.lazy + Suspense

Code splitting allows a React app to load only the code that’s needed for the current view, reducing initial bundle size and improving performance. In React, we can implement it using React.lazy for component-level lazy loading, combined with Suspense to show a fallback while the component is loading. For example:

For route-level splitting, we can lazy-load page components in combination with React Router, so each route only loads the necessary bundle.

Overall, code splitting improves performance, reduces initial load time, and makes large React apps more scalable.

面试加分点

4、what is the best way to add a global store to your react app or project?

关键词拆解:

  1. Global store

    • 意思是全局状态管理,让不同组件可以共享数据
    • 常见用途:用户登录信息、主题状态、购物车、全局配置等
  2. Best way

    • 考察你对 React 状态管理工具的了解
    • 不仅要能实现,还要考虑性能、易用性、可维护性
  3. React app / project

    • 前端应用,需要在组件树中共享状态

核心考点:

拆解小问题:

  1. 小型应用或者少量状态怎么办?

    • React Context + useReduceruseState 即可
  2. 中大型应用怎么办?

    • 使用 Redux ToolkitZustand 等高性能全局状态库
  3. 其他优化?

    • 只让需要的组件订阅状态,避免全局 Context 导致不必要渲染
    • 使用 immutable updates / selectors

The best way to add a global store in a React app depends on the size and complexity of the project. For small to medium apps, React Context combined with useReducer or useState is sufficient for managing global state like theme, user info, or UI preferences. For larger applications, I usually prefer Zustand, which provide scalable and performant global state management. These tools offer features like centralized state, selectors for efficient re-rendering, and middleware support for side effects. The key is to choose a solution that balances simplicity, maintainability, and performance, ensuring only the components that need the state are re-rendered when it changes.

 

5、give me an example of a basic react ssr implementation

这个问题了解即可,因为手动实现SSR非常复杂,因为工程化成本极高、数据需要预取、路由需要同步、维护压力很大。不如多了解nextjs的特点。

关键词拆解:

  1. SSR (Server-Side Rendering)

    • React 在服务器端生成 HTML,而不是只在浏览器端渲染
    • 优点:更快首屏渲染(FCP)SEO 更好用户体验提升
  2. Basic implementation

    • 不要求复杂功能,只需要一个能在服务器返回 HTML 的示例
  3. React SSR

    • 需要用到 react-dom/server 的 API,比如 renderToStringrenderToNodeStream

核心考点:

✅ Basic React SSR Example (Without Next.js)

Project Structure

1、React Component (App.js)

2、Server Entry (server.js)

This uses Node.js + Express + ReactDOMServer to render a React component to HTML on the server.

3、Client Hydration (client.js)

To make the server-rendered HTML interactive, you call hydrateRoot on the client:

➡️ What this demonstrates to an interviewer

 

Short version you can say in the interview:

A basic SSR setup uses ReactDOMServer.renderToString() on the server to generate HTML, sends that to the client, and then uses hydrateRoot() to attach React to the existing HTML. This gives faster initial load and better SEO. Next.js automates this, but this is the simplest manual implementation.

面试加分点

6、what is react fiber and how does it differ from the old reconciliation algorithm?

关键词拆解:

  1. React Fiber

    • React 16 引入的 新渲染引擎
    • 解决旧版本渲染性能问题,支持 增量渲染(incremental rendering)任务优先级调度
  2. Old reconciliation algorithm

    • React 15 及之前的 stack reconciler
    • 渲染是 同步的、阻塞的,一次渲染整个组件树
  3. How it differs

    • 核心考点:性能优化增量渲染可中断更新优先级调度

拆解小问题:

  1. 旧算法的缺点?

    • 所有更新都是同步完成 → 大组件树更新可能阻塞 UI
    • 没有任务优先级 → 动画、交互可能卡顿
  2. Fiber 的优势?

    • 支持 可中断渲染
    • 可以按照 优先级调度任务
    • 将渲染拆成小的单元(fiber)
    • 更好支持 异步渲染动画和交互平滑

简要回答:

React Fiber is the new reconciliation algorithm and rendering engine introduced in React 16. Its main goal is to make rendering more incremental, interruptible, and responsive. In the old stack reconciler, updates were synchronous and blocking — when a large component tree needed updating, the entire tree would render before the browser could handle user interactions, leading to potential UI jank. Fiber breaks rendering work into small units called fibers, which can be paused, aborted, or assigned different priority levels. This allows React to interrupt long rendering tasks, handle high-priority updates like user input first, and continue low-priority tasks later.

 

In short, Fiber improves performance, responsiveness, and scheduling flexibility compared to the old synchronous algorithm.

面试加分点

7、how does React determine when to rerender a component?

关键词拆解:

  1. Rerender a component

    • React 什么时候会重新执行函数组件的渲染逻辑
  2. Determine when

    • 考察对 React 更新机制的理解
  3. Function components only

    • 不考虑类组件,只关注函数组件和 Hooks

核心考点:

拆解小问题:

  1. 哪些操作会触发函数组件 rerender?

    • State 更新useState / useReducer
    • Props 改变 → 父组件传入的新值
    • Context 改变 → 使用 useContext 的组件
  2. React 内部如何判断?

    • 每次组件 rerender 时,函数会重新执行
    • 如果使用 React.memo,React 会对 props 做 浅比较,跳过不必要渲染
  3. 优化方法

    • React.memo 对函数组件做 memoization
    • useCallback / useMemo 对传递的 props 函数或对象做 memoization

 

简要回答:

In React function components, a component rerenders whenever its state, props, or context changes. Specifically:

  1. State updates via useState or useReducer trigger a rerender, and the component function executes again.
  2. Props changes from the parent component also trigger a rerender — even if the value seems the same, a new object or function reference will cause rerender.
  3. Context changes — if the component consumes a context with useContext, it rerenders when the context value changes.

To optimize performance, we can use React.memo to memoize the component and useCallback or useMemo to memoize props or functions passed down, so React can skip unnecessary rerenders.

 

In short, React rerenders function components based on state, props, or context changes, and memoization techniques can help prevent unneeded updates.

面试加分点

8、what are concurrent features in react and how do they help?

关键词拆解:

  1. Concurrent features

    • React 18 引入的新特性,用于 并发渲染(concurrent rendering)
    • 允许 React 在渲染大组件树时 可中断、可调度、优先处理重要任务
  2. How do they help

    • 考察你对 性能优化、用户体验提升 的理解

核心考点:

拆解小问题:

  1. 为什么需要 concurrent features?

    • 在大应用里,渲染复杂组件树可能阻塞 UI
    • 用户输入或动画可能卡顿
  2. Concurrent features 提供了什么能力?

    • 可中断渲染(interruptible rendering)
    • 任务优先级调度(prioritization)
    • 批量更新(automatic batching)
    • Transitions → 优先保证高优先级交互流畅
  3. 具体帮助表现在哪?

    • 保证 用户输入响应及时
    • 首屏渲染顺畅
    • 大数据更新不会阻塞 UI

Concurrent features is introduced in React 18, allow React to render components concurrently rather than blocking the main thread. These features enable interruptible rendering, task prioritization, and smoother user experiences. For example, React can pause rendering a low-priority update, handle user input immediately, and then resume rendering. React also provides Transitions, which help distinguish between urgent updates like typing and non-urgent updates like rendering a large list. Overall, concurrent features help keep the UI responsive, improve performance in large applications, and allow React to handle multiple tasks efficiently without blocking user interactions.

面试加分点

9、explain react's batching behavior and what changed in react 18?

类似的问题还有:react中state更新之后,组件为什么不会立即同步更新?react中的batching在react 18前后有什么区别?

关键词拆解:

  1. Batching behavior

    • 批量更新(batching)是指 React 会 把多个 state 更新合并在一次渲染中处理,避免重复渲染,提高性能
  2. What changed in React 18

    • 考察你对 React 18 新特性(自动批量更新、并发渲染) 的理解

核心考点:

拆解小问题:

  1. 什么是 batching?

    • 如果在同一事件中多次调用 setState,React 会把更新合并,只触发一次渲染
  2. React 17 及以前的限制?

    • 批量更新只在 React 事件处理函数内部生效
    • setTimeout、promise.then、原生事件中调用 setState 会触发多次渲染
  3. React 18 新特性?

    • Automatic Batching → 扩展到 所有异步上下文
    • 多个 state 更新无论在事件、setTimeout、promise 或 fetch 回调中,都会合并成一次渲染
  4. 优势?

    • 减少渲染次数 → 提升性能
    • 更一致的 UI 更新

 

Batching in React is the process of merging multiple state updates into a single render to improve performance. In React 17 and earlier, batching only worked inside React event handlers. Updates in setTimeout, promises, or native event handlers would trigger separate renders. In React 18, automatic batching was introduced, which extends batching to all updates, including asynchronous callbacks. Now multiple state updates inside promises, setTimeout, fetch, or any async operations are combined into a single render, reducing unnecessary renders and improving performance.

 

In short, React 18 makes batching more consistent and efficient, helping applications render faster and maintain smoother UI updates.

面试加分点

10、what is the difference between useMemo and useCallback and when you shouldn't use them

 

react hooks面试题这篇文档里面有详细解释。

useMemo and useCallback are both React hooks used for memoization, but they serve different purposes.

You shouldn’t use them for every function or value. For cheap calculations or simple functions, the overhead of memoization may outweigh its benefits. Overusing these hooks can increase memory usage and code complexity.

 

In short, useMemo → cache value, useCallback → cache function, and only use them when they provide a performance benefit.

面试加分点

11、How does Suspense work in react and what are some real use cases beyond lazy loading?

react 和 nextjs 原理这篇文档中有详细解释。

Suspense is React’s mechanism for handling asynchronous rendering. It works by letting components throw a Promise when they’re not ready yet, and a surrounding Suspense boundary catches it and shows a fallback UI until the data or resource is ready. This makes async flows much smoother compared to manually managing loading states in every component. Beyond lazy loading, Suspense has several real use cases: Data fetching with libraries like React Query. Image loading, where the UI waits for an image resource before rendering it. Server Components and streaming SSR in React 18, where Suspense boundaries allow the server to progressively stream UI chunks. Prefetching UI, letting React prepare parts of the UI in the background before the user navigates to them. Overall, Suspense is a general async boundary pattern that improves both developer experience and user-perceived performance.

除了 lazy loading,还有什么实际场景?

12、what is useImperativeHandle in react and when should it be used?

react 和 nextjs 原理这篇文档中有详细解释。

useImperativeHandle is a specialized hook that allows a child component to customize the instance value it exposes to its parent via a ref.

It must be used in conjunction with forwardRef. Instead of granting the parent full access to the underlying DOM node, which can be risky, you can restrict the API to specific methods—like focus(), scrollIntoView(), or resetForm().

This is a great tool for encapsulating internal logic. However, it should be used sparingly(俭省地) because it promotes a command-driven (imperative) style of programming, which goes against React's data-driven (declarative) nature. Most of the time, 'lifting state up' is the preferred approach.

面试加分点:

  1. "Customize the instance value":比 "control what is exposed" 更符合官方文档的定义,显得专业。
  2. "Restrict the API":强调了安全性。直接暴露整个 DOM 节点(默认行为)会让父组件能随意修改子组件的内部状态,通过这个 Hook 你可以只给父组件“你允许它做的”。
  3. "Encapsulating internal logic":体现了封装思想。
  4. "Declarative vs Imperative"这是全场最佳加分点。React 提倡声明式(数据驱动 UI),而 ref 调用是命令式。提到这一点说明你深刻理解 React 的设计哲学。

面试官可能追问:

"Why use this instead of just passing a state down?"

13、how do you optimize large lists in react?

When a list hits thousands of items, the bottleneck isn't React's state logic—it's the DOM overhead. The browser struggles to calculate the layout and paint for thousands of nodes, leading to laggy scrolling and high memory usage.

My primary solution is List Virtualization (or windowing). Instead of rendering the full dataset, we only mount the items currently visible in the viewport plus a small buffer for smooth scrolling.

In terms of implementation, I usually choose react-window over the older react-virtualized. It's a complete rewrite that is much lighter (~2KB vs ~33KB) and faster. If I need more flexibility for complex or headless layouts, I'd look into @tanstack/react-virtual.

To ensure this remains performant, I always:

  1. Memoize the row component using React.memo so that scrolling doesn't trigger unnecessary re-renders of the visible items.
  2. Use stable keys instead of array indices to help React's reconciliation.
  3. For dynamic heights, I'd use a VariableSizeList or a library like react-virtuoso that handles auto-measuring out of the box.

Overall, it's about keeping the DOM footprint constant, regardless of whether the list has 100 or 100,000 items."

面试得分点:

指出了性能根源:提到 "DOM overhead""Layout/Paint" 说明你懂浏览器底层,而不只是会写代码。

展现了选型决策力:对比 react-windowreact-virtualized 的体积和背景(同一个作者的重写版),面试官非常喜欢听这种有依据的技术选型。

补充了实战细节:提到 React.memoStable Keys 以及处理 Dynamic Heights 的方案,证明你有实际处理复杂长列表的经验。

提到了 "Constant DOM footprint":这是一个很高级的总结词,意指无论数据多大,DOM 节点数量始终保持恒定。

 

如果面试官追问:“如果不准用第三方库,你怎么实现简单的虚拟列表? 你可以简述思路:监听容器的 onScroll 事件,根据 scrollTop 计算出当前 visible 区域的 startIndexendIndex,然后只 slice 数据数组进行渲染,并用一个 padding 或巨大的占位 div 撑开总高度以维持滚动条位置。

 

14、how does useRef differ from useState?

react hooks面试题这篇文档里面有详细解释。

Both useState and useRef can persist values across renders, but useState is reactive and triggers re-render when updated, so it’s used for UI state. useRef is more like a persistent container whose .current value can change without causing re-render, so it’s useful for DOM references, timers, previous values, or other mutable data that doesn’t directly affect the UI.

 

15、how does react handle hydration in SSR and what problem can arise?

这个面试题还是很常见的,主要是想考察你对 SSR(服务端渲染) 底层机制的理解,以及你是否处理过真实的“线上环境不一致”问题。虽然说纯react项目很少自己做ssr,但是nextjs里面还是有这方面的概念,所以考察是很正常的。

 

1️⃣ Keywords

2️⃣ Core Concepts

3️⃣ Sub-questions

4️⃣ Simple English Answer

In SSR, React renders the initial HTML on the server. When this HTML reaches the browser, React performs Hydration, which is the process of attaching event listeners to the existing DOM nodes instead of recreating them.

The most common issue is a Hydration Mismatch. This happens when the server-rendered HTML doesn't perfectly match the client’s first render.

Common causes include:

The consequence is usually a performance hit (hit本意是打、击。这里可以理解为性能下降), as React might bail out(跳伞、紧急救援,这里可以理解为中止渲染) and re-render the entire tree to fix the mismatch. To avoid this, I ensure that any client-specific logic is wrapped in useEffect.

5️⃣ Problems & Solutions

Common problems:

Solutions:

Rule of thumb: Server and client must render the same HTML during the first render.

 

追问:在 Next.js 中,如果你必须在 SSR 页面显示客户端的时间,你会怎么做?How would you handle rendering client-specific data, like a timestamp or browser-only info, without causing a Hydration error?

In Next.js, to render client-specific data safely, I usually follow one of these two patterns:

1. The useEffect Pattern (Most Common): I initialize the state with null or a placeholder and update it inside useEffect. Since useEffect only runs on the client after hydration, it ensures the initial server-rendered HTML matches the client's first render.

2. Next.js dynamic with ssr: false: If a specific component relies heavily on browser APIs (like a clock or a map), I use Next.js's dynamic import with the ssr: false option. This tells Next.js to skip rendering that component on the server entirely, avoiding any mismatch from the start.

Which one to choose? I prefer useEffect for small text changes to keep the SEO benefit of the rest of the page. I use dynamic for heavy, client-only widgets to keep the server-side bundle light.

中文逻辑拆解:

  1. useEffect 方案(最标准)

    • 逻辑:让服务端和客户端第一次渲染都显示“加载中”或“空串”,等挂载(Mount)完成后,再在 useEffect 里更新成真正的时间。
    • 优点:符合 React 生命周期,安全可靠。
  2. dynamic 禁用 SSR 方案(最省事)

    • 逻辑:直接告诉 Next.js:“这个组件你别在服务器跑了,只在浏览器跑。”
    • 优点:完全规避 Mismatch,代码更简洁。

 

https://nextjs.org/docs/app/guides/lazy-loading#nextdynamic

image-20260508143158185

16、what causes a memory leak in a react component using useEffect

1️⃣ Keywords

2️⃣ Core Concepts

3️⃣ Sub-questions

4️⃣ Simple English Answer

A memory leak in React occurs when a component is unmounted, but some of its processes—like event listeners, timers, or subscriptions—continue to run in the background.

To prevent this, I always use the cleanup function in useEffect. For example:

While React no longer warns about 'setting state on unmounted components' in newer versions, it's still a best practice to clean up to avoid unexpected behavior and memory bloat.

5️⃣ Solution

Common fixes:

Example:

This prevents the effect from running after the component is unmounted.

17、How can API calls cause memory leaks in react?

1️⃣ Keywords

2️⃣ Core Concepts

3️⃣ Sub-questions

4️⃣ Simple English Answer

API calls can cause memory leaks when they finish after the component unmounts. If the promise resolves and calls setState, React warns about a memory leak. This happens because the async callback is still in memory. The component is gone, but the request is still running. Without cleanup, React cannot release the resources.

 

To handle this, I use an AbortController to cancel the fetch request in the cleanup function.

5️⃣ Solution

Main solutions:

  1. Cancel the request

    • Use AbortController for fetch
  2. Ignore the result after unmount

    • Track a mounted flag

Example with AbortController:

This ensures the API call does not update state after the component is unmounted.

18、How do event listeners create memory leaks in react?

1️⃣ Keywords

2️⃣ Core Concepts

3️⃣ Sub-questions

4️⃣ Simple English Answer

Event listeners can cause memory leaks when they are added but never removed. The listener still exists after the component unmounts. It keeps a reference to the component’s callback. Because of this, the component cannot be garbage collected. Re-renders may also add the same listener multiple times.

 

I use window.removeEventListener to ensure they don't stay in memory.

5️⃣ Solution

Fix: always clean up listeners

Best practices:

This prevents memory leaks caused by event listeners.

19、Can setInterval or setTimeout cause memory leaks in react?

1️⃣ Keywords

2️⃣ Core Concepts

3️⃣ Sub-questions

4️⃣ Simple English Answer

Yes, setInterval and setTimeout can cause memory leaks in React. If they are not cleared, they keep running after the component unmounts. The timer callback keeps references to the component’s state and props. This prevents the component from being garbage collected. setInterval is worse because it runs repeatedly.

 

I use clearTimeout or clearInterval to clear timers in cleanup function.

5️⃣ Solution

Always clear timers in cleanup

Best practices:

This prevents memory leaks caused by timers.

20、Can closures or refs cause memory leaks in react?

1️⃣ Keywords

2️⃣ Core Concepts

3️⃣ Sub-questions

4️⃣ Simple English Answer

Beyond just timers and listeners, closures and refs can also lead to memory leaks if not managed carefully.

For Closures: The issue usually stems from 'stale closures' inside a useEffect or an event handler. If a long-running function captures large objects or props but is never cleaned up, those variables cannot be garbage collected. This is especially common when a closure is passed to a global object or an external library that outlives the component. (闭包问题通常源于“陈旧闭包”。如果一个长时间运行的函数捕获了大对象或 Props 却未被清理,这些变量就无法被垃圾回收。这在闭包被传给全局对象或生命周期比组件更长的外部库时非常常见。)

For Refs: useRef is often used to store mutable values that don't trigger re-renders, but since the ref.current persists for the entire component lifetime, it can hold onto large DOM nodes or heavy class instances indefinitely. If I manually attach a DOM element to a ref, I must ensure that I nullify ref.current during cleanup if that reference is being shared or stored externally. (useRef 存储的变量在组件整个生命周期内都存在。如果 ref.current 持有了巨大的 DOM 节点或实例,内存就会持续占用。如果我手动将 DOM 挂载到 ref,我会确保在清理函数中将 ref.current 置为 null。)

To prevent these, I rely on strict cleanup logic and tools like the Chrome Memory Profiler to take heap snapshots and identify detached nodes or retained objects. (为了防止这些问题,我依赖严格的清理逻辑,并使用 Chrome 内存分析器通过堆快照来定位脱离的 DOM 节点或被保留的对象。)

面试得分点:

引入 "Stale Closures"(陈旧闭包):这是 React 开发中的高频痛点,提到它说明你对 Hooks 的底层机制(闭包)有深入理解。

区分了“内部存储”与“外部共享”:强调了闭包传给“外部库”或“全局对象”时的风险,这才是真正的泄露大坑。

提到 "Nullifying Refs":手动将 ref.current = null 是一个很资深的习惯,尤其是在处理第三方库插件(如图表库、地图库)时。

提到了工具:提到 "Chrome Memory Profiler""Heap Snapshots" 证明你具备实战排查能力,而不仅仅是纸上谈兵。

5️⃣ Solution

Closures:

Refs:

Rule of thumb: If something lives longer than the component, it can cause a memory leak.